package com.zjk.toolkit.ratelimiter.aspect;

import com.zjk.toolkit.ratelimiter.annotation.DoRateLimiter;
import com.zjk.toolkit.ratelimiter.service.impl.IRateLimiterServiceImpl;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class DoRateLimiterAspect {

    @Pointcut("@annotation(com.zjk.toolkit.ratelimiter.annotation.DoRateLimiter)")
    public void aopPoint(){

    }

    @Around("aopPoint() && @annotation(doRateLimiter)")
    public Object doRateLimiter(ProceedingJoinPoint joinPoint, DoRateLimiter doRateLimiter) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Method method = getMethod(joinPoint);
        IRateLimiterServiceImpl rateLimiterService = new IRateLimiterServiceImpl();
        return rateLimiterService.access(joinPoint, method, doRateLimiter, args);
    }

    private Method getMethod(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        return joinPoint.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }
}
